package com.naiterui.ehp.ps.sms.factory;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.naiterui.ehp.bp.utils.encypt.MD5;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.ps.sms.utils.HttpRequestUtils;
import com.naiterui.ehp.ps.sms.utils.constants.SmsConstants;

import lombok.extern.slf4j.Slf4j;

/**
 * 容联短信平台API
 *
 * @author
 * @since 1.0.0
 */
@Slf4j
public class CloopenApi {

    private static final String BASE_URL = ConfigUtil.getString(SmsConstants.API_CLOOPEN_BASE_URL);// api请求基础路径
    private static final String API_VERSION = ConfigUtil.getString(SmsConstants.API_CLOOPEN_VERSION);// 接口版本号
    private static final String API_SID = ConfigUtil.getString(SmsConstants.API_CLOOPEN_SID);// 用户ID
    private static final String APPID = ConfigUtil.getString(SmsConstants.API_CLOOPEN_APPID);// APPID
    private static final String TOKEN = ConfigUtil.getString(SmsConstants.API_CLOOPEN_TOKEN);// TOKEN
    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final int MAX_REPORT_COUNT = 100;// 批量获取状态报告返回最大记录数
    private static final int REPORT_TYPE_STATUS = 1;// 状态报告

    private static String API_MESSENG_SEND_URL;// 发送短信URL
    private static String API_BATCH_STATUS_REPORT_URL;// 批量获取状态报告URL

    static {
        StringBuffer sendBuffer = new StringBuffer();
        sendBuffer.append(BASE_URL).append("/").append(API_VERSION).append("/Accounts/").append(API_SID);
        String baseUrl = sendBuffer.toString();
        API_MESSENG_SEND_URL = baseUrl + "/SMS/TemplateSMS";
        API_BATCH_STATUS_REPORT_URL = baseUrl + "/SMS/GetArrived";
    }

    /**
     * 单条发送短信
     * MontnetSms.siggleSend()
     *
     * @param phone
     * @param content
     *
     * @return
     *
     * @Author
     * @Date 2017年7月26日
     * @since 1.0.0
     */
    public static String siggleSend(String phone, String templateId, String[] datas) {

        // 获取鉴权加密串
        String timestamp = DATE_FORMATTER.format(Calendar.getInstance().getTime());
        String sigParam = encryptSignature(timestamp);
        String url = API_MESSENG_SEND_URL + "?sig=" + sigParam;
        JSONObject params = new JSONObject();
        params.put("to", phone);// 接收的用户手机号码
        params.put("appId", APPID);// APPID
        params.put("templateId", templateId);// 模板ID
        params.put("datas", datas);// 短信内容参数

        // 请求header信息
        Map<String, String> headers = getBaseHeader(timestamp);
        if (headers == null) {
            log.error("[发送短信，容联平台]--获取鉴权头信息出错,手机号电话号码:[{}] 模板ID:[{}] 模板参数:[{}] timestamp:[{}]", phone, templateId, datas, timestamp);
            return null;
        }

        // 调用容联API短信接口
        log.info("调用容联发送短信接口: url : {}, params : {}, header : {}", url, params.toJSONString(), headers);
        String result = HttpRequestUtils.doPostBasicAndHeader(url, params.toJSONString(), headers);
        return result;
    }

    /**
     * 批量获取状态报告
     * MontnetApi.getBatchReport()
     *
     * @return
     *
     * @Author
     * @Date 2017年7月28日
     * @since 1.0.0
     */
    public static String getBatchReport() {
        // 获取鉴权加密串
        String timestamp = DATE_FORMATTER.format(Calendar.getInstance().getTime());
        String sigParam = encryptSignature(timestamp);
        String url = API_BATCH_STATUS_REPORT_URL + "?sig=" + sigParam;

        JSONObject params = new JSONObject();
        params.put("appId", APPID);// APPID
        params.put("smsType", REPORT_TYPE_STATUS);
        params.put("count", String.valueOf(MAX_REPORT_COUNT));

        // 请求header信息
        Map<String, String> headers = getBaseHeader(timestamp);
        if (headers == null) {
            log.error("[获取状态报告，容联平台]--获取鉴权头信息出错");
            return null;
        }
        // 调用容联API接口
        log.info("调用容联获取状态报告接口: url : {}, params : {}, header : {}", url, params.toJSONString(), headers);
        String result = HttpRequestUtils.doPostBasicAndHeader(url, params.toJSONString(), headers);
        return result;
    }

    /**
     * 获取加密串
     * CloopenSms.encryptSignature()
     *
     * @param timestamp
     *
     * @return
     *
     * @Author
     * @Date 2017年7月26日
     * @since 1.0.0
     */
    private static String encryptSignature(String timestamp) {
        String sig = API_SID + TOKEN + timestamp;
        String signature = MD5.md5(sig);
        return signature;
    }

    /**
     * 获取通用请求头
     * CloopenSms.getBaseHeader()
     *
     * @return
     *
     * @throws UnsupportedEncodingException
     * @Author
     * @Date 2017年7月26日
     * @since 1.0.0
     */
    private static Map<String, String> getBaseHeader(String timestamp) {
        String authSrc = API_SID + ":" + timestamp;
        String auth = "";
        try {
            auth = new String(Base64.getEncoder().encode(authSrc.getBytes("utf-8")));
        } catch (UnsupportedEncodingException e) {
            log.error("发送容联短信，转换编码失败,authSrc:{}", authSrc, e);
            return null;
        }
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json;charset=utf-8");
        headers.put("Accept", "application/json;");
        headers.put("Authorization", auth);
        return headers;
    }

}
